
import getObject3D from 'components/Three/Controller/fns/getObject3D';
import * as THREE from 'three';
import { Clock } from 'three';
import { GLTF as ThreeGLTF } from 'three/examples/jsm/loaders/GLTFLoader';

//parser.options.path

export class GLTF {

    /** 动画时钟 */
    clock = new Clock();

    /** Object3D */
    scene: ThreeGLTF;

    /** 动画得名称 */
    animationName?: string;

    /** 动画对象 */
    animation?: THREE.AnimationClip;

    /** 动画混淆器 */
    mixer?: THREE.AnimationMixer;

    /** 动画控制器 */
    action?: THREE.AnimationAction

    parser: {
        options: {
            path: string 
        }
    }

    constructor(scene: ThreeGLTF, path: string) {
        this.scene = scene;
        this.parser = { options: { path } };
    }

    play = (name?: string) => {
        this.stop();
        this.animation = this.scene.animations.filter(e => e.name === name)[0];
        if (this.animation) {
            this.animationName = name;
            this.mixer = new THREE.AnimationMixer(this.scene.scene);
            this.action = this.mixer.clipAction(this.animation);
            this.action.play();
        }
    }

    stop = () => {
        this.action?.stop();
        this.animationName = undefined;
        this.action = undefined;
        this.mixer = undefined;
    }
}

export default class Element<K extends keyof IObject3DMap = keyof IObject3DMap, IData = any> {

    /** 版本 */
    version: number = 0;

    /** 唯一标识 */
    uuid: string;

    /** 名称 */
    name: string;

    /** 原件类型 */
    type: K;

    /** 携带的数据 */
    data?: IData;

    /** three 对象 */
    object3D: IObject3DMap[K];

    constructor(type: K, uuid: string, object3D: IObject3DMap[K]) {
        this.type = type;
        this.object3D = object3D;
        this.uuid = uuid;
        this.name = `${type}-${uuid}`;
    }

    /** 获取object3D */
    getObject3D = (): THREE.Object3D | undefined => getObject3D(this);
}

export interface IObject3DMap {

    /** GLTF 模型 */
    gltf: GLTF;

    /** 灯光 */
    light: THREE.Light;

    /** 标记 */
    tag: THREE.Mesh;

    /** 通用 */
    object3D: THREE.Object3D;
}


